import { loadImage } from "@/utils";
import { getScreenSize } from "@/utils";
import { useUIStore } from "@/store/uiStore";
import { useTimeStore } from "@/store/timeStore";
import Curosrs from "@/assets/images/tiles/cursors.zh-CN.png";
import { useWeatherStore, WeatherType } from "@/store/weatherStore";

/**
 * 时钟UI
 * @param x 时钟UI左上角x坐标
 * @param y 时钟UI左上角y坐标
 * @param width 时钟UI宽度
 * @param height 时钟UI高度
 * @param zIndex 时钟UI层级
 */
export class ClockUI {
  private timeStore = useTimeStore();
  private uiStore = useUIStore();
  private weatherStore = useWeatherStore();

  constructor() {
    const gameTime = this.timeStore.gameTime;
    const { width: screenWidth } = getScreenSize();

    loadImage(Curosrs).then((res) => {
      // 注册时钟背景
      this.uiStore.registerElement("clock", {
        visible: true,
        zIndex: 10,
        resources: res,
        type: "clockBg",
        sourceRect: {
          x: 333,
          y: 432,
          width: 72,
          height: 57,
        },
        position: { x: screenWidth - 190, y: 10 },
        size: { width: 180, height: 143 },
      });

      // 注册时钟指针
      this.uiStore.registerElement("clockPointer", {
        visible: true,
        zIndex: 13,
        resources: res,
        type: "clockHand",
        sourceRect: {
          x: 324,
          y: 477,
          width: 7,
          height: 19,
        },
        position: { x: screenWidth - 138, y: 14 },
        size: { width: 18, height: 48 },
        rotationOrigin: { x: 10, y: 42 },
        rotation: 180,
      });

      // 注册时钟时间文本
      this.uiStore.registerElement("clockTimeText", {
        visible: true,
        zIndex: 11,
        type: "clockTimeText",
        text: this.timeStore.formattedTime,
        position: { x: screenWidth - 75, y: 90 },
        textOptions: {
          font: "bold 18px Arial",
          fillStyle: "#461802",
          textAlign: "center",
          textBaseline: "middle",
          shadowColor: "#000000",
          shadowBlur: 2,
          shadowOffsetX: 0,
          shadowOffsetY: 1,
        },
      });

      // 注册日期时间文本
      this.uiStore.registerElement("clockDateText", {
        visible: true,
        zIndex: 12,
        type: "clockDateText",
        text: `${gameTime.day}日 ${gameTime.weekday}`,
        position: { x: screenWidth - 75, y: 34 },
        textOptions: {
          font: "bold 16px Arial",
          fillStyle: "#461802",
          textAlign: "center",
          textBaseline: "middle",
          shadowColor: "#000000",
          shadowBlur: 2,
          shadowOffsetX: 0,
          shadowOffsetY: 1,
        },
      });
      // 注册天气图标
      this.uiStore.registerElement("weatherIcon", {
        visible: true,
        zIndex: 13,
        resources: res,
        type: "weatherIcon",
        sourceRect: this.getWeatherIconSourceRect(),
        position: { x: screenWidth - 118, y: 50 },
        // size: { width: 65, height: 28 },
        size: { width: 29, height: 20 },
      });
    });
  }

  // 更新时钟UI显示的时间和日期
  update() {
    if (this.uiStore.uiElements["clockTimeText"]) {
      this.uiStore.updateElement("clockTimeText", {
        text: this.timeStore.formattedTime,
      });
    }

    if (this.uiStore.uiElements["clockDateText"]) {
      this.uiStore.updateElement("clockDateText", {
        text: `${this.timeStore.gameTime.day}日 ${this.timeStore.gameTime.weekday}`,
      });
    }

    if (this.uiStore.uiElements["weatherIcon"]) {
      this.uiStore.updateElement("weatherIcon", {
        sourceRect: this.getWeatherIconSourceRect(),
      });
    }

    // 更新时钟指针旋转角度
    if (this.uiStore.uiElements["clockPointer"]) {
      // 获取当前小时和分钟
      const hours = this.timeStore.gameTime.hours;
      const minutes = this.timeStore.gameTime.minute;

      // 游戏中从6点到凌晨2点，时钟用180度表示
      // 计算当前时间在一天中的进度
      let progress = 0;

      // 6点到24点
      if (hours >= 6 && hours < 24) {
        // 计算6点到24点之间的进度，占总进度的18/20
        progress = (hours - 6 + minutes / 60) / 20;
      }
      // 0点到2点
      else if (hours >= 0 && hours < 2) {
        // 计算0点到2点之间的进度，占总进度的2/20，但要加上前面的18/20
        progress = (hours + minutes / 60) / 20 + 18 / 20;
      }
      // 2点到6点（这段时间应该是跳过的）
      else {
        progress = 1; // 指向2点位置
      }

      // 将进度转换为角度，180度范围
      const angle = progress * Math.PI; // 180度 = π弧度

      // 计算指针角度
      const { width: screenWidth } = getScreenSize();
      const hourAngle = Math.PI - angle;
      const rotationOriginX = 10 + progress * 18;
      const positionX = screenWidth - 138 - progress * 10;
      const positionY = 20 - progress * 4;

      this.uiStore.updateElement("clockPointer", {
        rotation: -hourAngle,
        rotationOrigin: {
          x: rotationOriginX / 2,
          y: 42,
        },
        position: {
          x: positionX,
          y: positionY,
        },
      });
    }
  }

  // 渲染时钟UI
  render(ctx: CanvasRenderingContext2D, uiCanvasRef: HTMLCanvasElement) {
    if (!ctx) return;
    if (!uiCanvasRef) return;

    const uiElements = this.uiStore.uiElements;
    const sortedElements = Object.entries(uiElements)
      .map(([key, el]) => ({ key, el }))
      .sort((a, b) => (a.el?.zIndex || 0) - (b.el?.zIndex || 0));

    for (const { key, el } of sortedElements) {
      if (!el || !el.visible) continue;

      // 处理时钟背景
      if (
        el.type === "clockBg" &&
        el.resources &&
        el.sourceRect &&
        el.position &&
        el.size
      ) {
        const destX = Math.floor(el.position.x);
        const destY = Math.floor(el.position.y);
        const destWidth = Math.floor(el.size.width);
        const destHeight = Math.floor(el.size.height);

        ctx.drawImage(
          el.resources,
          el.sourceRect.x,
          el.sourceRect.y,
          el.sourceRect.width,
          el.sourceRect.height,
          destX,
          destY,
          destWidth,
          destHeight
        );
      }
      // 处理时钟指针
      else if (
        el.type === "clockHand" &&
        el.resources &&
        el.sourceRect &&
        el.position &&
        el.size &&
        el.rotationOrigin
      ) {
        const destX = Math.floor(el.position.x);
        const destY = Math.floor(el.position.y);
        const destWidth = Math.floor(el.size.width);
        const destHeight = Math.floor(el.size.height);

        ctx.save();

        // 计算旋转中心点（相对于画布）
        const rotationX = destX + el.rotationOrigin.x;
        const rotationY = destY + el.rotationOrigin.y;

        // 移动到旋转中心点
        ctx.translate(rotationX, rotationY);

        // 应用旋转
        ctx.rotate(el.rotation || 0);

        // 绘制图像，需要将位置调整为相对于旋转中心点的坐标
        ctx.drawImage(
          el.resources,
          el.sourceRect.x,
          el.sourceRect.y,
          el.sourceRect.width,
          el.sourceRect.height,
          -el.rotationOrigin.x,
          -el.rotationOrigin.y,
          destWidth,
          destHeight
        );

        // 恢复画布状态
        ctx.restore();
      }
      // 处理文本
      else if (
        (el.type === "clockDateText" || el.type === "clockTimeText") &&
        el.text &&
        el.textOptions &&
        el.position
      ) {
        ctx.save();
        Object.assign(ctx, el.textOptions);
        ctx.fillText(el.text, el.position.x, el.position.y);
        ctx.restore();
      }
      // 处理天气图标
      else if (
        el.type === "weatherIcon" &&
        el.sourceRect &&
        el.resources &&
        el.position &&
        el.size
      ) {
        const destX = Math.floor(el.position.x);
        const destY = Math.floor(el.position.y);
        const destWidth = Math.floor(el.size.width);
        const destHeight = Math.floor(el.size.height);

        ctx.drawImage(
          el.resources,
          el.sourceRect.x,
          el.sourceRect.y,
          el.sourceRect.width,
          el.sourceRect.height,
          destX,
          destY,
          destWidth,
          destHeight
        );
      }
      // 处理其他图像类型
      else if (
        el.type === "image" &&
        el.sourceRect &&
        el.resources &&
        el.position &&
        el.size
      ) {
        const destX = Math.floor(el.position.x);
        const destY = Math.floor(el.position.y);
        const destWidth = Math.floor(el.size.width);
        const destHeight = Math.floor(el.size.height);

        ctx.drawImage(
          el.resources,
          el.sourceRect.x,
          el.sourceRect.y,
          el.sourceRect.width,
          el.sourceRect.height,
          destX,
          destY,
          destWidth,
          destHeight
        );
      }
    }
  }

  /**
   * 获取天气图标资源矩形
   * @returns 天气图标资源矩形
   */
  private getWeatherIconSourceRect() {
    const weatherType = this.weatherStore.currentWeather;

    switch (weatherType) {
      case WeatherType.CLEAR:
        return {
          x: 341,
          y: 421,
          width: 12,
          height: 8,
        };
      case WeatherType.RAIN:
        return {
          x: 365,
          y: 421,
          width: 12,
          height: 8,
        };
    }
  }
}
